// Subrange Types (子范围类型) 示例
// 演示 Pascal 中子范围类型的各种用法
program p_20_subrange_types;

{$mode objfpc}{$H+}
// {$mode objfpc} 启用 Object Pascal 模式
// {$H+} 启用长字符串支持（AnsiString）

// 引入单元文件
uses
  SysUtils;  // 系统工具单元，包含常用的系统函数

// 定义子范围类型
type
  // 年龄范围 (0-150岁)
  TAge = 0..150;
  
  // 百分比范围 (0-100%)
  TPercentage = 0..100;
  
  // 大写字母范围
  TUpperCaseLetter = 'A'..'Z';
  
  // 小写字母范围
  TLowerCaseLetter = 'a'..'z';
  
  // 数字字符范围
  TDigitChar = '0'..'9';
  
  // 数组索引范围
  TArrayIndex = 1..10;

// 检查年龄是否有效的过程
procedure CheckAge(age: TAge);
begin
  WriteLn('  年龄 ', age, ' 是有效的');
end;

// 检查百分比是否有效的过程
procedure CheckPercentage(percent: TPercentage);
begin
  WriteLn('  百分比 ', percent, '% 是有效的');
end;

// 程序主入口
begin
  WriteLn('=== Pascal 子范围类型示例 ===');
  WriteLn;
  
  // 1. 基本子范围类型使用
  WriteLn('1. 基本子范围类型使用:');
  var age: TAge = 25;
  var percent: TPercentage = 85;
  var letter: TUpperCaseLetter = 'M';
  
  WriteLn('  年龄: ', age);
  WriteLn('  百分比: ', percent, '%');
  WriteLn('  字母: ', letter);
  
  // 调用过程验证子范围类型
  CheckAge(age);
  CheckPercentage(percent);
  
  WriteLn;
  
  // 2. 字符子范围类型
  WriteLn('2. 字符子范围类型:');
  var digit: TDigitChar = '5';
  var lowerChar: TLowerCaseLetter = 'x';
  var upperChar: TUpperCaseLetter = 'K';
  
  WriteLn('  数字字符: ', digit);
  WriteLn('  小写字母: ', lowerChar);
  WriteLn('  大写字母: ', upperChar);
  
  WriteLn;
  
  // 3. 子范围类型数组
  WriteLn('3. 子范围类型数组:');
  var scores: array[TArrayIndex] of TPercentage;
  
  // 初始化数组
  for var i := 1 to 10 do
    scores[i] := i * 10;  // 10, 20, 30, ..., 100
  
  WriteLn('  分数数组:');
  for var i := 1 to 10 do
    WriteLn('    第', i, '个学生: ', scores[i], '%');
  
  WriteLn;
  
  // 4. 子范围类型范围检查
  WriteLn('4. 子范围类型范围检查:');
  var validAge: TAge = 30;
  WriteLn('  有效年龄: ', validAge);
  
  // 注意：以下代码在编译时会出错，因为超出范围
  // var invalidAge: TAge = 200;  // 编译错误：超出范围 0..150
  
  WriteLn('  子范围类型会在编译时检查值的有效性');
  
  WriteLn;
  
  // 5. 子范围类型与循环
  WriteLn('5. 子范围类型与循环:');
  Write('  大写字母A到E: ');
  for var c: TUpperCaseLetter := 'A' to 'E' do
    Write(c, ' ');
  WriteLn;
  
  Write('  百分比0到10: ');
  for var p: TPercentage := 0 to 10 do
    Write(p, ' ');
  WriteLn;
  
  WriteLn;
  
  // 6. 子范围类型转换
  WriteLn('6. 子范围类型转换:');
  var baseValue: Integer = 75;
  var percentValue: TPercentage = TPercentage(baseValue);  // 类型转换
  
  WriteLn('  整数值: ', baseValue);
  WriteLn('  转换为百分比类型: ', percentValue, '%');
  
  WriteLn;
  WriteLn('演示了 Pascal 中子范围类型的各种用法');
  
  // 等待用户按键，防止程序窗口立即关闭
  ReadLn;
end.